package packing;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;


/**
 * Storage class for question content.
 * 
 * This class will retrieve the information about a question and store it for
 * later use. Functions are provided for easy access to specific information. It
 * will not handle exceptions leaving it up to the calling function.
 * 
 * An iterator is provided for retrieving files of a question. It has two
 * states, PROVIDED and SOLUTION. Setting the state resets the iterator and
 * changes what it returns. PROVIDED returns values that will be provided to the
 * student; while SOLUTION returns files found in the solution set. The
 * differences between the two is, which input and output are return and
 * instructions and scoring criteria will be left out of both, see appropriate
 * function to retrieve those files.
 */
public class Question implements Iterator<SourceFile>
{
	public static final int PROBLEM = 0, SOLUTION = 1;

	private int iteration;
	private int lastItem;

	int id, version, points, type;
	String title, typeDescription;
	ArrayList<SourceFile> files = new ArrayList<SourceFile>();

	/**
	 * Grab all relevant files related to a question given its id and version
	 * 
	 * @param conn
	 *            A database connection
	 * @param id
	 *            The id of the question
	 * @param ver
	 *            The question version
	 * @throws SQLException
	 *             All exception thrown by database is not handled
	 */
	public Question(Connection conn, int id, int ver) throws SQLException
	{
		this.id = id;
		this.version = ver;

		// Get all Blob with this question
		PreparedStatement pstmt = conn
				.prepareStatement("SELECT source_file_name AS \"File Name\", "
						+ "source_file AS \"Source\", kin "
						+ "FROM source_file INNER JOIN question "
						+ "ON question.question_id = source_file.question_id "
						+ "WHERE question.question_id = ?");
		pstmt.setInt(1, id);
		ResultSet rset = pstmt.executeQuery();

		while (rset.next())
		{
			files.add(new SourceFile(rset.getString("File Name"), rset
					.getInt("kin"), rset.getBlob("Source")));
		}
		pstmt.close();
		rset.close();

		// Get the question name and points value
		pstmt = conn
				.prepareStatement("SELECT question_title, points FROM question_content "
						+ "INNER JOIN question ON question.question_content_id = "
						+ "question_content.question_content_id WHERE question_id=?");
		pstmt.setInt(1, id);
		rset = pstmt.executeQuery();

		rset.next();
		title = rset.getString("question_title");
		points = rset.getInt("points");
		rset.close();
		pstmt.close();

		// Get the type of question
		pstmt = conn
				.prepareStatement("SELECT type_code, type_description FROM question_type "
						+ "INNER JOIN question "
						+ "ON question.question_type_code = question_type.type_code "
						+ "WHERE question.question_id=?");
		pstmt.setInt(1, id);
		rset = pstmt.executeQuery();

		rset.next();
		type = rset.getInt("type_code");
		typeDescription = rset.getString("type_description");
		rset.close();
		pstmt.close();
	}

	/**
	 * Get the question instruction
	 * 
	 * @return SourceFile containing the question instruction
	 */
	public SourceFile getInstructions()
	{
		for (int i = 0; i < files.size(); i++)
			if (KinID.instr(files.get(i).kin))
			{
				System.out.println("We are in this loop.");
				return files.get(i);
			}	
		System.out.println("MESSAGE SHOULD PRINT RIGHT BEFORE THE EXCEPTION");
		return null;
	}

	/**
	 * Get the scoring criteria for the question
	 * 
	 * @return SourceFile containing the scoring criteria
	 */
	public SourceFile getCriteria()
	{
		for (int i = 0; i < files.size(); i++)
			if (KinID.criteria(files.get(i).kin))
				return files.get(i);
		return null;
	}

	/*
	 * Below are the Iterator functions
	 */
	public void setIterator(int type)
	{
		iteration = type;
		lastItem = -1;
	}

	/**
	 * Return if the list is empty or not
	 */
	public boolean hasNext()
	{
		for (int i = lastItem + 1; i < files.size(); i++)
			if (iteration == PROBLEM)
			{
				if (KinID.provided(files.get(i).kin))
					return true;
			} else if (KinID.solution(files.get(i).kin))
				return true;
		return false;
	}

	/**
	 * Return the next SourceFile in the list
	 */
	public SourceFile next()
	{
		for (int i = ++lastItem; i < files.size(); i++)
			if (iteration == PROBLEM)
			{
				if (KinID.provided(files.get(i).kin))
				{
					lastItem = i;
					return files.get(i);
				}
			} else if (KinID.solution(files.get(i).kin))
			{
				lastItem = i;
				return files.get(i);
			}
		return null;
	}

	/**
	 * Remove from list. NOT IMPLEMENTED
	 */
	public void remove()
	{
	}

}
